1 00:00:00,800 --> 00:00:01,910 Welcome back. 2 00:00:01,910 --> 00:00:07,670 In this lecture we're going to be learning about instance streaming, which is an awesome feature that 3 00:00:07,670 --> 00:00:13,850 allows us to dynamically load and unload 3D content in the workspace of our game. 4 00:00:13,850 --> 00:00:20,390 Enabling instant streaming can help to improve join times, improve memory usage, improve performance, 5 00:00:20,390 --> 00:00:25,670 and enables some level of detail features to optimize distant models and terrain. 6 00:00:25,670 --> 00:00:32,120 Instance streaming is a must have for any game, with large maps as reducing join times and improving 7 00:00:32,120 --> 00:00:36,770 memory usage and performance is important for good user experience in your games. 8 00:00:37,310 --> 00:00:43,670 Instance streaming is going to be enabled by default on every new game that you create in Roblox. 9 00:00:43,670 --> 00:00:50,030 So if you go to the workspace and if you scroll down in your properties menu, you should see this streaming 10 00:00:50,030 --> 00:00:53,960 section and streaming enabled will be checked by default. 11 00:00:53,960 --> 00:00:57,440 And if we uncheck it, then we'll disable streaming. 12 00:00:58,450 --> 00:01:02,500 And the difference between streaming and streaming disabled. 13 00:01:02,500 --> 00:01:08,710 If a player joins your game, if streaming is disabled, then all of the parts inside of the workspace, 14 00:01:08,710 --> 00:01:14,140 all of the models, all of the descendants will be replicated right when the player joins, and then 15 00:01:14,140 --> 00:01:21,070 the game loaded event will fire after all of those instances have loaded for that particular player. 16 00:01:21,070 --> 00:01:27,250 However, if you have streaming turned on, then what's going to happen is that only models and parts 17 00:01:27,250 --> 00:01:33,160 that are within a certain radius of the replication focus for a player are going to be loaded, while 18 00:01:33,160 --> 00:01:37,690 everything else, all the other base parts in your game are going to be ignored. 19 00:01:37,690 --> 00:01:42,790 This is how we can improve performance, memory usage, and join times for your game. 20 00:01:42,790 --> 00:01:46,720 And that's by not loading everything in the game all at once. 21 00:01:47,290 --> 00:01:52,780 Now we're going to learn about all of these different properties inside of streaming enabled, and we're 22 00:01:52,780 --> 00:02:00,010 also going to take a look at some additional properties for models that show up when you enable streaming. 23 00:02:00,010 --> 00:02:05,500 So there is this property called Model streaming mode for all of the models in your game when you have 24 00:02:05,500 --> 00:02:07,000 instant streaming turned on. 25 00:02:07,000 --> 00:02:11,920 But when you turn this off and you go and check your model, as you can see, that property is no longer 26 00:02:11,920 --> 00:02:12,400 there. 27 00:02:13,000 --> 00:02:18,160 So the first property we're going to take a look at for streaming enabled is going to be the Streaming 28 00:02:18,160 --> 00:02:19,840 Integrity mode. 29 00:02:19,870 --> 00:02:25,150 Now, the streaming integrity mode by default is going to be set to disabled. 30 00:02:25,150 --> 00:02:32,260 And disabled means that the game is not going to pause, or the client is not going to pause simulation 31 00:02:32,260 --> 00:02:34,300 for any reason whatsoever. 32 00:02:34,300 --> 00:02:40,090 However, these two other options, which is minimum radius, pause and pause outside of the loaded 33 00:02:40,090 --> 00:02:41,890 area, are a little bit different. 34 00:02:42,400 --> 00:02:48,880 So with minimum radius pores, what's going to happen is that if any instance, such as a model or a 35 00:02:48,880 --> 00:02:56,170 part in the game reaches within the minimum radius around the player and it's not streamed in, then 36 00:02:56,170 --> 00:02:58,810 the player is going to have their game paused. 37 00:02:59,710 --> 00:03:02,740 And then with pause outside of loaded area. 38 00:03:02,740 --> 00:03:04,720 This one's a little bit different. 39 00:03:04,720 --> 00:03:12,370 Where simulation around the replication of focus property of our player is going to be paused when the 40 00:03:12,370 --> 00:03:18,190 replication focus instances bounding box is not inside of a streamed area. 41 00:03:18,220 --> 00:03:19,330 What do I mean by this? 42 00:03:19,330 --> 00:03:23,530 Well, every single player in your game has a property called replication Focus. 43 00:03:23,530 --> 00:03:29,650 By default, the replication focus property is going to be the primary part of your player's character, 44 00:03:29,650 --> 00:03:31,360 which is your humanoid root part. 45 00:03:31,360 --> 00:03:38,140 However, the server can manually set the replication focus to be a different part in the workspace, 46 00:03:38,140 --> 00:03:40,630 and this part has a bounding box. 47 00:03:40,630 --> 00:03:45,550 For example, this part right here has a volume, and this volume right? 48 00:03:45,550 --> 00:03:48,610 The border of this volume is considered its bounding box. 49 00:03:48,610 --> 00:03:55,840 So whenever you have your replication focus bounding box, enter into an area that has not been streamed 50 00:03:55,840 --> 00:03:56,290 in. 51 00:03:56,290 --> 00:04:03,430 Then the area around that replication focus part is going to be paused, simulation is going to be paused, 52 00:04:04,030 --> 00:04:06,370 and we're going to take a look at this behavior in a moment. 53 00:04:07,450 --> 00:04:14,980 So if I were to have streaming enabled, turned off and I would go to play my game. 54 00:04:17,380 --> 00:04:23,380 As you can see, all of the parts in my workspace and even this model that's far away from me are all 55 00:04:23,380 --> 00:04:24,220 loaded in. 56 00:04:24,220 --> 00:04:31,420 I have access to all of the instances within my workspace, just as I would expect without having streaming 57 00:04:31,420 --> 00:04:32,170 enabled. 58 00:04:32,680 --> 00:04:37,180 However, if I were to go and enable streaming. 59 00:04:38,340 --> 00:04:40,800 And I'll just keep this at the default settings for now. 60 00:04:42,110 --> 00:04:45,200 So let me move this back to defaults. 61 00:04:45,200 --> 00:04:46,430 Keep all these on the default. 62 00:04:46,430 --> 00:04:48,800 And then our to go and play my game. 63 00:04:49,930 --> 00:04:54,400 As you can see right away, I am missing a ton of these parts. 64 00:04:54,400 --> 00:04:57,130 I only have a certain chunk of these parts loaded. 65 00:04:57,160 --> 00:05:01,150 I don't have that model loaded, and I certainly don't have the rest of those parts loaded. 66 00:05:01,150 --> 00:05:07,150 And if I go ahead and take a look at my workspace, as you can see, there's not as many parts inside 67 00:05:07,150 --> 00:05:09,760 of this folder that I should have. 68 00:05:10,300 --> 00:05:16,360 And this model that was supposed to be off in the distance has no descendants inside of it. 69 00:05:16,360 --> 00:05:18,640 So this is what Streaming Enabled does. 70 00:05:18,640 --> 00:05:22,000 When I go and start walking around, it will start loading. 71 00:05:22,000 --> 00:05:26,980 In these instances, as you can see, more are appearing in my folder. 72 00:05:27,560 --> 00:05:32,420 And if I were to go walk to where my model is, which is down over here. 73 00:05:34,320 --> 00:05:36,780 And as you can see, more of these parts are loading in. 74 00:05:36,960 --> 00:05:38,130 Eventually, there we go. 75 00:05:38,130 --> 00:05:39,960 I hit my model right here. 76 00:05:40,520 --> 00:05:47,300 And as you can see now, this model has these base part children that have streamed in to my player. 77 00:05:48,200 --> 00:05:54,980 Now these parts are streaming in around me based on these two properties right here streaming minimum 78 00:05:54,980 --> 00:05:57,980 radius and streaming target radius. 79 00:05:58,010 --> 00:06:04,070 You can basically think of these as two circular zones around the player, where parts and models are 80 00:06:04,070 --> 00:06:06,500 streamed in at different priorities. 81 00:06:06,530 --> 00:06:12,770 So with streaming minimum radius, this is a circular zone around your player, where parts of models 82 00:06:12,770 --> 00:06:16,760 are going to be streamed in at the absolute highest priority. 83 00:06:17,030 --> 00:06:22,460 Whereas the streaming target radius is going to be a zone around the player, where the server is going 84 00:06:22,460 --> 00:06:27,140 to be much more relaxed when trying to stream objects to our player. 85 00:06:27,740 --> 00:06:34,580 Now these two values are going to influence heavily your streaming integrity mode when you don't have 86 00:06:34,580 --> 00:06:35,870 it set to disable. 87 00:06:35,870 --> 00:06:41,840 So you have two of these different properties and minimum radius pause and pause outside loaded area. 88 00:06:41,870 --> 00:06:44,420 Now remember minimum radius pause. 89 00:06:44,420 --> 00:06:48,320 What's going to happen is that the client is going to pause their game. 90 00:06:48,320 --> 00:06:54,230 When any instances that are not streamed in enter into our minimum radius. 91 00:06:54,230 --> 00:06:58,880 So it's going to pause the game, and it's going to wait until those instances get streamed in. 92 00:06:58,880 --> 00:07:01,040 And then it's going to unpause the game. 93 00:07:01,490 --> 00:07:04,820 To better visualize this, I've created these two circles. 94 00:07:04,820 --> 00:07:07,610 You can imagine the black dot as our player. 95 00:07:07,610 --> 00:07:13,670 You can imagine the red circle as the minimum radius, and you can imagine the blue circle as the target 96 00:07:13,670 --> 00:07:14,480 radius. 97 00:07:14,810 --> 00:07:20,960 So when we have objects in our game, for example, if we have like models outside here, these models 98 00:07:20,960 --> 00:07:27,650 are not going to be streamed in for our player because they are not within the target radius or the 99 00:07:27,650 --> 00:07:28,730 minimum radius. 100 00:07:28,730 --> 00:07:35,000 However, once one of these models gets within our target radius, then the server is going to be like, 101 00:07:35,000 --> 00:07:41,660 okay, I should try to replicate this part or this model to my player as soon as possible, but I'm 102 00:07:41,660 --> 00:07:45,500 not going to be that urgent about it because it's only within the target radius. 103 00:07:45,500 --> 00:07:53,090 However, if this model gets to this minimum radius and it hasn't been streamed in yet, so if it gets 104 00:07:53,090 --> 00:07:58,280 in there, then the server is going to be like, whoa, the player has not loaded this part in. 105 00:07:58,280 --> 00:08:04,400 And if we have um, minimum radius pause enabled, then this player is going to pause their game. 106 00:08:04,400 --> 00:08:09,950 The server at the highest priority is going to try to replicate this model apart to our player. 107 00:08:09,950 --> 00:08:13,640 And once it does that then the player can unpause their game. 108 00:08:14,090 --> 00:08:20,330 So that means it's very important to keep a sizable gap between these two radiuses. 109 00:08:20,330 --> 00:08:27,620 And that's because if the radius of our target radius was the same as the minimum radius, then we have 110 00:08:27,620 --> 00:08:33,530 literally zero opportunity for the server to load in parts between those two zones. 111 00:08:33,530 --> 00:08:39,110 Instead, these parts or models are going to instantly hit the minimum radius, and our player is going 112 00:08:39,110 --> 00:08:42,350 to keep pausing the game over and over and over again. 113 00:08:42,350 --> 00:08:45,590 And that's going to be a big problem for user experience. 114 00:08:46,570 --> 00:08:53,890 So to show minimum radius, pause and action, what I'm going to do is I'm going to duplicate this parts 115 00:08:53,890 --> 00:08:55,450 folder a lot. 116 00:08:55,450 --> 00:09:01,120 So I'm just going to duplicate it and then duplicate it a bit more and duplicate it again. 117 00:09:01,120 --> 00:09:04,240 So there's a lot of stuff that the player would have to stream in over here. 118 00:09:05,800 --> 00:09:08,680 And then we can go ahead and pick one of these random parts. 119 00:09:08,680 --> 00:09:14,560 Preferably I'll do one in the middle, like I'll pick this one and I'm going to copy the position of 120 00:09:14,560 --> 00:09:15,370 this part. 121 00:09:16,450 --> 00:09:18,310 And then we can go and play our game. 122 00:09:19,680 --> 00:09:20,910 And. 123 00:09:21,570 --> 00:09:22,980 If you see here. 124 00:09:22,980 --> 00:09:27,690 As you can see, we only have these parts streamed in and we don't see any of those parts streamed in 125 00:09:27,690 --> 00:09:28,680 all the way out there. 126 00:09:28,680 --> 00:09:34,050 But if we go ahead and take a look at the server, as you can see, the server has access to all of 127 00:09:34,050 --> 00:09:35,670 these instances in our game. 128 00:09:35,670 --> 00:09:37,440 And as you can see, our player is right here. 129 00:09:37,710 --> 00:09:42,240 But as you saw earlier, our player can only see these particular parts. 130 00:09:43,500 --> 00:09:49,320 Now, if I were to update the position of my part to that position I copied, you're going to see the 131 00:09:49,320 --> 00:09:57,780 game pause for a split second as the server tries to stream all of these instances to the player. 132 00:09:57,780 --> 00:09:59,100 So if I hit enter. 133 00:09:59,960 --> 00:10:06,380 As you can see, that was pretty quick, but there was a little pop up where the game paused simulation 134 00:10:06,380 --> 00:10:10,550 until we were able to stream all of these other instances in. 135 00:10:11,510 --> 00:10:17,450 Now, because we're running this on a local server, obviously all of these objects replicate into the 136 00:10:17,450 --> 00:10:23,000 player is going to be really fast, but in an actual server setting, this is going to be much slower. 137 00:10:23,000 --> 00:10:27,140 So the player is going to have their game paused for a longer period of time. 138 00:10:27,980 --> 00:10:29,390 Now to show the problem. 139 00:10:29,390 --> 00:10:36,800 When our target radius is the same as our minimum radius, we're going to set it to 64, the exact same 140 00:10:36,800 --> 00:10:38,180 as our minimum radius. 141 00:10:38,180 --> 00:10:39,890 And we're going to play test the game. 142 00:10:39,890 --> 00:10:45,860 And while our player walks around and starts loading in these parts, as you can see, the game is going 143 00:10:45,860 --> 00:10:54,740 to start freezing or pausing itself because these instances are hitting the minimum radius and they 144 00:10:54,740 --> 00:10:55,640 haven't loaded in yet. 145 00:10:55,640 --> 00:10:59,030 So the client's going to freak out and be like, oh, we haven't loaded them in yet. 146 00:10:59,030 --> 00:11:00,740 Let's go ahead and pause the game. 147 00:11:01,220 --> 00:11:08,870 So when I start walking, as you can see, we're getting these pop ups of game play paused, game play 148 00:11:08,870 --> 00:11:09,470 paused. 149 00:11:09,470 --> 00:11:16,010 And if you had a lot of parts and models in your game, this would obviously be pausing for a lot longer, 150 00:11:16,640 --> 00:11:21,440 and it would just completely ruin the user experience, because every time the player walks around, 151 00:11:21,440 --> 00:11:24,050 they have to keep pausing the game. 152 00:11:24,050 --> 00:11:25,310 And that's just stupid. 153 00:11:26,080 --> 00:11:32,530 So you always want to make sure that your streaming target radius is at least double of what your minimum 154 00:11:32,530 --> 00:11:33,520 radius is. 155 00:11:33,520 --> 00:11:39,760 And since the smallest number you can set for the minimum radius is 64, then that means your streaming 156 00:11:39,760 --> 00:11:44,440 target radius should at least be 128 studs. 157 00:11:44,800 --> 00:11:47,470 So that's double the minimum radius. 158 00:11:47,470 --> 00:11:49,720 And now if we go and playtest our game. 159 00:11:51,050 --> 00:11:53,780 When our player goes and walks around. 160 00:11:55,020 --> 00:11:58,230 As you can see, we are no longer pausing anymore. 161 00:11:58,230 --> 00:12:00,120 We're loading in these objects. 162 00:12:00,120 --> 00:12:06,630 The game is not freezing, and even if I go walk over here and load in this part or this model, because 163 00:12:06,630 --> 00:12:14,850 this model entered into the target radius, it had a chance to replicate to our player before it hit 164 00:12:14,850 --> 00:12:16,290 the minimum radius. 165 00:12:16,290 --> 00:12:17,580 And that's very important. 166 00:12:18,030 --> 00:12:24,840 So whenever you have minimum radius pores enabled, you want to make sure that your target radius is 167 00:12:24,840 --> 00:12:27,630 at least double your minimum radius. 168 00:12:27,630 --> 00:12:34,170 That way you're giving these parts and these models an opportunity to stream in to the client before 169 00:12:34,170 --> 00:12:38,820 the client, you know, pauses the game because it hit the minimum radius. 170 00:12:40,040 --> 00:12:44,600 Now this other option is going to be called pause outside loaded area. 171 00:12:44,600 --> 00:12:48,800 And what's going to happen with this one, if you remember earlier, is that simulation is going to 172 00:12:48,800 --> 00:12:51,920 be paused around a replication focus. 173 00:12:52,570 --> 00:12:57,640 If we look here in the Roblox documentation, as you can see, every single player in our game has a 174 00:12:57,640 --> 00:13:03,340 property called Replication Focus, and it says the Replication Focus player property sets the part 175 00:13:03,340 --> 00:13:06,220 to focus replication around a player. 176 00:13:06,220 --> 00:13:10,900 Different Roblox systems that communicate over the network, like physics, replicate at different rates, 177 00:13:10,900 --> 00:13:14,320 depending on how close objects are to the replication focus. 178 00:13:14,320 --> 00:13:19,420 When this property is nil, it reverts to its default behavior, which is to treat the local player's 179 00:13:19,420 --> 00:13:23,470 characters primary part as the replication focus. 180 00:13:23,470 --> 00:13:25,990 So that would be your humanoid root part. 181 00:13:26,110 --> 00:13:30,310 You set this property with a server script and not a local script. 182 00:13:30,490 --> 00:13:35,860 So to demonstrate this replication focus property, what we're going to do is we're going to set up 183 00:13:35,860 --> 00:13:38,290 a one player server in the test tab. 184 00:13:38,290 --> 00:13:43,120 So that way we can visualize both the client and the server at the same time. 185 00:13:44,450 --> 00:13:48,830 And what I'm going to do here for my player is I'm going to take one of these parts. 186 00:13:48,830 --> 00:13:50,420 I'm going to duplicate it. 187 00:13:52,040 --> 00:13:59,840 And I'm going to go to my properties panel just to make sure that it is collidable, and I'll un anchor 188 00:13:59,840 --> 00:13:59,960 it. 189 00:13:59,960 --> 00:14:03,200 So that way my player has network ownership over this part. 190 00:14:03,440 --> 00:14:07,820 And because I have network ownership here on the client, that means if I move it around on the client, 191 00:14:08,300 --> 00:14:11,300 we should be able to see that movement on the server. 192 00:14:12,090 --> 00:14:13,380 So. 193 00:14:15,600 --> 00:14:17,970 It's actually not moving, which is kind of interesting. 194 00:14:18,090 --> 00:14:19,140 Did I anchor it? 195 00:14:19,410 --> 00:14:20,880 I did un anchor it. 196 00:14:21,060 --> 00:14:22,890 Give me network ownership. 197 00:14:23,970 --> 00:14:25,080 So let me try moving again. 198 00:14:25,080 --> 00:14:25,890 Okay, there we go. 199 00:14:25,890 --> 00:14:32,220 Now I have a network ownership over this part, which means when I move it, the server observes those 200 00:14:32,220 --> 00:14:34,140 changes when I move it around. 201 00:14:34,830 --> 00:14:40,350 So now, because I have network ownership over this part, I want to change the replication focus for 202 00:14:40,350 --> 00:14:43,230 my player to be set to this part. 203 00:14:43,500 --> 00:14:48,030 So I'm going to take this part, and I'm going to set its parent equal to the workspace. 204 00:14:48,030 --> 00:14:50,640 So that way I can reference it easier. 205 00:14:52,920 --> 00:14:58,290 And we're going to do is we're going to get the player service and get player one, and we're going 206 00:14:58,290 --> 00:15:03,660 to update the replication focus property equal to workspace dot part. 207 00:15:04,310 --> 00:15:10,730 And then if we go ahead and hit enter, we executed this code in our command line. 208 00:15:10,730 --> 00:15:14,780 And now this part should be my new replication focus. 209 00:15:14,780 --> 00:15:22,070 So if I zoom out here and if I go to try to load the parts that are over here and I move this part around, 210 00:15:22,970 --> 00:15:28,760 as you can see now, this part is acting as my replication focus instead of my player. 211 00:15:28,940 --> 00:15:31,400 So even if my player here. 212 00:15:32,000 --> 00:15:33,620 If I were to walk away. 213 00:15:33,710 --> 00:15:35,210 Actually, I can't walk. 214 00:15:36,630 --> 00:15:42,420 So as you can see, all this stuff outside of my replication focus has simulation pores. 215 00:15:42,420 --> 00:15:45,030 So even though I'm trying to walk around, I can't. 216 00:15:45,420 --> 00:15:51,150 I will only be able to walk around as soon as this part comes close enough again. 217 00:15:51,150 --> 00:15:53,250 And now I am able to walk around. 218 00:15:53,490 --> 00:16:01,590 So as you can see, when we have it set to the pores outside of loaded area, when I move this replication 219 00:16:01,590 --> 00:16:03,540 focus far enough away. 220 00:16:04,480 --> 00:16:07,450 Now I am unable to move my character around. 221 00:16:07,630 --> 00:16:13,720 That's because simulation for my character has stopped, because we're set on the pause outside of the 222 00:16:13,720 --> 00:16:18,760 loaded area property, and this part is acting as my replication focus. 223 00:16:18,760 --> 00:16:23,920 So it isn't until this replication focus comes close enough that I'm able to move my character again, 224 00:16:24,820 --> 00:16:27,850 but let me have my character walk far enough away. 225 00:16:28,740 --> 00:16:33,840 So that way we definitely know that my player is not streaming in this model over here. 226 00:16:33,900 --> 00:16:40,320 And if I go and move my part over there, as you can see, my part has now loaded in this model. 227 00:16:40,320 --> 00:16:45,510 And that's because the server is treating this part as the replication focus for my player. 228 00:16:45,900 --> 00:16:53,130 Now, since the game is only going to pause when the bounding box of this replication focus enters into 229 00:16:53,130 --> 00:16:55,080 an area that has not streamed in. 230 00:16:55,770 --> 00:17:03,030 That means if we hit an area very quickly where we have not loaded any stuff in, then the game is going 231 00:17:03,030 --> 00:17:09,360 to pause because again, this replication focus will be in an area where stuff has not loaded in. 232 00:17:09,360 --> 00:17:15,390 So for example, if you were to teleport the player somewhere and you had it set to pause outside of 233 00:17:15,390 --> 00:17:20,880 loaded area, well that means the player is now going to be in in an area that has not been streamed 234 00:17:20,880 --> 00:17:21,120 in. 235 00:17:21,120 --> 00:17:23,580 So the game is going to pause. 236 00:17:24,700 --> 00:17:28,600 The next property we're going to take a look at here is called streaming Out Behavior. 237 00:17:28,600 --> 00:17:33,520 And this property determines how instances should stream out in our game. 238 00:17:34,310 --> 00:17:38,540 The default is set to low memory and low memory. 239 00:17:38,540 --> 00:17:45,230 What this basically does is that it will stream in all of these parts or objects in our game, and it 240 00:17:45,230 --> 00:17:53,390 won't stream them out until the game recognizes that the computer or our device is running low on memory. 241 00:17:53,390 --> 00:17:59,750 So once it starts running low on memory, then the game will start streaming out stuff that is farthest 242 00:17:59,750 --> 00:18:04,730 away from us until it's satisfied with how much memory we have left. 243 00:18:05,710 --> 00:18:09,460 The other option is called opportunistic. 244 00:18:09,580 --> 00:18:16,510 And what, this, uh, what this property does is that any instances that exit outside of our target 245 00:18:16,510 --> 00:18:23,920 radius will be immediately streamed out, and then any instances that reach into our target radius will 246 00:18:23,920 --> 00:18:25,360 obviously be streamed in. 247 00:18:25,390 --> 00:18:32,260 So if you have any model or part that get outside of our target radius for our players replication focus, 248 00:18:32,260 --> 00:18:34,360 then they're going to immediately stream out. 249 00:18:35,180 --> 00:18:37,130 So let's go ahead and take a look at this. 250 00:18:37,130 --> 00:18:38,780 If we go and playtest the game. 251 00:18:40,820 --> 00:18:44,540 And if we just, let's say we start walking this way. 252 00:18:44,570 --> 00:18:48,140 These parts should start to slowly disappear. 253 00:18:49,370 --> 00:18:52,100 So I'm walking, I'm walking, I'm walking. 254 00:18:52,100 --> 00:18:52,820 There we go. 255 00:18:52,820 --> 00:18:57,800 And now these parts are beginning to unload as I get farther and farther away from them. 256 00:18:57,800 --> 00:19:00,140 And that's what the opportunistic mode does. 257 00:19:00,170 --> 00:19:06,830 Once these parts get outside of my target radius, they stream out, and then once they come back into 258 00:19:06,830 --> 00:19:08,360 my target radius. 259 00:19:09,350 --> 00:19:11,210 Then they'll start to stream back in. 260 00:19:11,210 --> 00:19:12,200 Just like that. 261 00:19:15,670 --> 00:19:20,620 Alrighty, the next part of instant streaming we're going to take a look at is this model streaming 262 00:19:20,620 --> 00:19:26,530 mode property that appears for all of the models in our game when we have instant streaming enabled. 263 00:19:26,890 --> 00:19:32,440 Now, this property determines how a model is going to be streamed in or streamed out. 264 00:19:32,470 --> 00:19:36,730 The default is set to something called Non-atomic. 265 00:19:36,730 --> 00:19:43,330 And what Non-atomic means is that the children of a model will be streamed in or streamed out when they 266 00:19:43,330 --> 00:19:50,950 are within range, but any children within the model that are not 3D objects will not be streamed out. 267 00:19:50,950 --> 00:19:58,540 So when we have a model set to Non-atomic, that means the model itself will appear in our game. 268 00:19:58,690 --> 00:20:04,660 But any base part descendants that are not within range of our player will not be streamed in. 269 00:20:04,750 --> 00:20:11,050 So that means we will only see this model instance and none of the descendants until we get close enough 270 00:20:11,050 --> 00:20:13,270 to stream these base parts in. 271 00:20:13,270 --> 00:20:19,540 If this model had other children, for example, like a script, then the model and the script would 272 00:20:19,540 --> 00:20:24,670 be streamed in immediately for our player when they join the game on Non-atomic. 273 00:20:24,670 --> 00:20:30,280 But any of these base parts would not be streamed in until we got close enough where they hit our target 274 00:20:30,280 --> 00:20:31,090 radius. 275 00:20:31,450 --> 00:20:34,180 Now, atomic is the complete opposite. 276 00:20:34,180 --> 00:20:42,970 What atomic does is that it streams in the entire model when we get close enough to the model. 277 00:20:42,970 --> 00:20:47,650 So when the player joins the game, any models that are atomic and they aren't within range of the player 278 00:20:47,650 --> 00:20:53,740 will not be streamed in, even if they have, uh, descendants that aren't base parts. 279 00:20:53,740 --> 00:20:56,740 So the entire model won't appear in our game. 280 00:20:56,740 --> 00:21:02,860 But as soon as we get close enough to stream the model in, we hit one of these, uh, parts that are 281 00:21:02,860 --> 00:21:03,820 inside of the model. 282 00:21:03,820 --> 00:21:09,820 Then the entire model as a whole will stream into the game, and then when we get far enough away from 283 00:21:09,820 --> 00:21:13,270 it, then the entire model as a whole will stream out. 284 00:21:13,600 --> 00:21:17,200 So that's the difference between atomic and non-atomic. 285 00:21:17,650 --> 00:21:20,230 So let's first go ahead and take a look at Non-atomic. 286 00:21:22,070 --> 00:21:23,900 And we'll playtest our game. 287 00:21:27,000 --> 00:21:32,820 And if I go and walk towards the area where my model is, and actually before I do that, if we look 288 00:21:32,820 --> 00:21:38,820 in the workspace, as you can see, here is our model and we can see the script, which is a child of 289 00:21:38,820 --> 00:21:41,760 our model, but we don't see any of the base parts. 290 00:21:41,760 --> 00:21:48,090 It isn't until we get close enough where those parts have hit our target radius, where now we have 291 00:21:48,090 --> 00:21:51,000 streamed them in, and then when we walk away. 292 00:21:51,860 --> 00:21:56,840 Those parts when they leave are going to be streamed out just like that. 293 00:21:56,870 --> 00:22:02,750 However, our model and the script inside of our model, or any descendants in the model that aren't 294 00:22:02,750 --> 00:22:06,230 um, base parts will be left inside of here. 295 00:22:06,260 --> 00:22:07,880 Now, there is exceptions to this. 296 00:22:07,880 --> 00:22:13,430 For example, if parts in the model have children of their own, those will also be streamed out because 297 00:22:13,430 --> 00:22:15,620 they are children of those base parts. 298 00:22:15,620 --> 00:22:22,580 But any, uh, other descendants or children of this model that aren't parented to any base parts, 299 00:22:22,580 --> 00:22:24,950 they're going to remain inside of my model. 300 00:22:25,810 --> 00:22:32,740 However, once I swap this mode to atomic and then we were to go and play the game when we take a look 301 00:22:32,740 --> 00:22:37,420 at our workspace, as you can see, we can no longer see the model anymore, right? 302 00:22:37,690 --> 00:22:40,660 If we go and walk towards the direction where our model is. 303 00:22:42,350 --> 00:22:48,890 Now the entire model streams in together, including the script and all of the descendants. 304 00:22:48,890 --> 00:22:50,930 And then when we go and walk away. 305 00:22:52,010 --> 00:22:54,320 The entire model should stream out. 306 00:22:55,330 --> 00:22:56,080 And there we go. 307 00:22:56,080 --> 00:22:58,570 We no longer see that model anymore. 308 00:23:00,090 --> 00:23:03,570 The other mode here is going to be called persistent. 309 00:23:03,840 --> 00:23:10,710 And what persistent means is that this model will immediately stream in when the player joins the game. 310 00:23:10,710 --> 00:23:11,700 No exceptions. 311 00:23:11,700 --> 00:23:16,620 So even if the player is not within range of this model, this model is going to be streamed in when 312 00:23:16,620 --> 00:23:17,460 the player joins. 313 00:23:17,460 --> 00:23:21,840 And this model is never going to be streamed out even if the player gets far enough away. 314 00:23:21,930 --> 00:23:29,670 So if I go and play test my game with a persistent model, as you can see, I see my model over there. 315 00:23:29,670 --> 00:23:34,140 And even if I were to walk really far away from my model. 316 00:23:34,910 --> 00:23:39,200 It is never going to stream out because we have it set to persistent. 317 00:23:39,200 --> 00:23:41,960 It will stay in our game forever. 318 00:23:43,220 --> 00:23:47,390 The last option we have here for our model is called persistent per player. 319 00:23:47,690 --> 00:23:53,690 Now this property works the exact same as atomic, but we can actually go out and pick which players 320 00:23:53,690 --> 00:23:54,650 in our game. 321 00:23:54,650 --> 00:24:00,740 We would like to have this model be persistently streamed for. 322 00:24:01,430 --> 00:24:08,990 So what I mean is that if we don't choose any players to be persistent for this model, then this model 323 00:24:08,990 --> 00:24:12,680 is just going to act as an atomic model for those players. 324 00:24:12,680 --> 00:24:18,380 However, if we pick a particular player in our game, let's say a player joins a game and we go throughout 325 00:24:18,380 --> 00:24:26,360 the map and pick certain persistent per player models to be always on the map for those particular players, 326 00:24:26,360 --> 00:24:28,880 then it's going to act as a persistent model. 327 00:24:29,720 --> 00:24:34,190 So to demonstrate this, we can set up a two player server instead. 328 00:24:35,450 --> 00:24:38,150 And here I have my two player setup. 329 00:24:38,480 --> 00:24:44,780 And as you can see, both of these players cannot see that model because it's currently acting as atomic. 330 00:24:44,780 --> 00:24:50,300 And that's because the server has not set for that particular model for a player to be persistent. 331 00:24:51,060 --> 00:24:55,290 Now, if I look on the server here, what I can go ahead and do is I can go ahead and pick one of these 332 00:24:55,290 --> 00:24:58,380 players to be persistent with this model. 333 00:24:58,980 --> 00:25:03,210 So what I can do is I can refer to the model in my workspace. 334 00:25:03,210 --> 00:25:05,940 It would be workspace dot model. 335 00:25:05,940 --> 00:25:10,110 And then we have a function which is add persistent player. 336 00:25:10,110 --> 00:25:15,030 And it says sets this model to be persistent for the specified player. 337 00:25:15,970 --> 00:25:18,130 So now we can go ahead and specify player. 338 00:25:18,130 --> 00:25:19,840 For example we could do player one. 339 00:25:19,840 --> 00:25:25,000 So I'll pass game dot players dot player one and then we'll hit enter. 340 00:25:25,390 --> 00:25:29,740 And now we have added player one to be persistent for this particular model. 341 00:25:29,740 --> 00:25:35,770 So if we go ahead and take a look at our game again with both of our players, as you can see now player 342 00:25:35,770 --> 00:25:39,610 one has loaded this model in because it's supposed to be persistent for us. 343 00:25:39,610 --> 00:25:42,580 But player two has not loaded the model in. 344 00:25:43,520 --> 00:25:50,150 I have to go and walk over here and actually stream in the model just like that to be able to see it. 345 00:25:50,150 --> 00:25:52,520 But then if I walk away from the model. 346 00:25:53,910 --> 00:25:57,330 The model is going to stream back out again for me just like that. 347 00:25:57,330 --> 00:26:01,710 And that's because player two is not set to be persistent with this model. 348 00:26:01,710 --> 00:26:07,380 However, player one, on the other hand, can walk away as far as he'd like and that model is going 349 00:26:07,380 --> 00:26:13,320 to remain visible for him, even if he's like a thousand studs away, it's always going to be there. 350 00:26:14,740 --> 00:26:19,540 So that is all of the different model streaming mode properties for models. 351 00:26:19,540 --> 00:26:25,120 However, there is one last property we need to look at within the workspace that actually affects this 352 00:26:25,120 --> 00:26:27,730 model streaming mode property. 353 00:26:28,260 --> 00:26:31,860 And that property is called model streaming behavior. 354 00:26:31,860 --> 00:26:33,330 And there's two different ones. 355 00:26:33,330 --> 00:26:36,420 There's one which is called legacy, which is the default. 356 00:26:36,420 --> 00:26:39,120 And there's another one here called improved. 357 00:26:39,120 --> 00:26:40,890 What's the difference between those two? 358 00:26:41,540 --> 00:26:49,790 Well, what improved does is that it takes non-atomic models and it only replicates those models when 359 00:26:49,790 --> 00:26:54,590 one of the base part descendants are within range to be streamed. 360 00:26:54,620 --> 00:27:01,640 So basically, in other words, if we have a model in our game like this one over here, and our player 361 00:27:01,640 --> 00:27:07,940 is not within range of any of the descendant based parts of this model, then the entire model itself 362 00:27:07,940 --> 00:27:12,440 will not be streamed into the game, even if it's set to atomic. 363 00:27:13,740 --> 00:27:20,040 That's because the improved mode for model streaming behavior basically forces all of the models in 364 00:27:20,040 --> 00:27:28,380 your game to respect this new property, where if the player is not within range of any of the descendant 365 00:27:28,380 --> 00:27:32,130 based parts of a model, then the entire model is going to be streamed out. 366 00:27:32,130 --> 00:27:38,670 Once the player actually gets within range of one of the base parts of the model, then it will stream 367 00:27:38,670 --> 00:27:40,260 the entire model in together. 368 00:27:40,260 --> 00:27:48,660 So even if your model was set to Nonatomic, where it would typically keep the model itself in the improved 369 00:27:48,660 --> 00:27:55,800 mode for model streaming behavior is not going to respect this property, and it's not going to stream 370 00:27:55,800 --> 00:28:00,720 this model to the player unless the player is within the range of one of these base parts. 371 00:28:02,070 --> 00:28:08,820 Now, the legacy mode, which we were on by default, allows us to control it through these different 372 00:28:08,820 --> 00:28:15,600 model streaming mode properties where any Non-atomic models and any non base part children of the model 373 00:28:15,600 --> 00:28:21,810 are going to be replicated when the player joins, regardless if that model is within range or not, 374 00:28:21,810 --> 00:28:27,420 and then any eligible children based parts of that model are going to be streamed in when the player 375 00:28:27,420 --> 00:28:28,320 is in range. 376 00:28:28,680 --> 00:28:36,570 So this model streaming behavior mainly affects the Nonatomic property for model streaming mode. 377 00:28:36,570 --> 00:28:43,230 So when we have it set to legacy, that means this model is going to stream in the model itself and 378 00:28:43,230 --> 00:28:43,920 the script. 379 00:28:43,920 --> 00:28:48,180 But if these base parts aren't in range, then it's not going to stream these base parts in. 380 00:28:48,390 --> 00:28:55,980 And then if we have it set to improved, then this entire model itself will not be streamed in and it 381 00:28:55,980 --> 00:28:59,910 will only stream in once the player is within range one of these base parts. 382 00:29:00,510 --> 00:29:02,370 So let's actually go ahead and take a look at that. 383 00:29:02,370 --> 00:29:05,340 We're going to keep our model at Nonatomic. 384 00:29:06,410 --> 00:29:12,080 And then we're going to go ahead and set it to improved. 385 00:29:12,650 --> 00:29:14,900 And then we can go ahead and playtest our game. 386 00:29:15,710 --> 00:29:20,780 And if we go ahead and take a look in the workspace, as you can see, our model does not exist within 387 00:29:20,780 --> 00:29:21,860 the workspace. 388 00:29:21,890 --> 00:29:26,780 It isn't until we get within range of one of those bass parts where the entire model becomes streamed 389 00:29:26,780 --> 00:29:32,720 in, and then when we go and walk away, the entire model is going to be streamed out because we are 390 00:29:32,720 --> 00:29:35,120 no longer within range of any of those bass parts. 391 00:29:35,120 --> 00:29:42,050 So just like that, even though that model is set to non-atomic, it is acting as an atomic model. 392 00:29:42,050 --> 00:29:47,030 And that's because we have set the model streaming behavior to be improved. 393 00:29:47,840 --> 00:29:53,780 Now, if we go ahead and swap model streaming behavior back to legacy or the default, and we go and 394 00:29:53,780 --> 00:29:54,860 play test the game. 395 00:29:55,930 --> 00:29:58,120 And we were to check the workspace. 396 00:29:58,120 --> 00:30:03,040 As you can see, we do see our model here, and we do see the script inside of it. 397 00:30:03,040 --> 00:30:08,740 And then any eligible base parts within our model are going to be streamed in once we get in range. 398 00:30:09,220 --> 00:30:12,190 So as you can see, all of the base parts pop in. 399 00:30:12,190 --> 00:30:13,750 And then when we walk away. 400 00:30:16,510 --> 00:30:22,600 All of the base parts should disappear just like that, but the entire model itself does not get streamed 401 00:30:22,600 --> 00:30:23,440 in or streamed out. 402 00:30:23,440 --> 00:30:26,800 It stays within our workspace. 403 00:30:28,020 --> 00:30:33,900 Now, there is one other thing to mention with the improved model streaming behavior, and that's if 404 00:30:33,900 --> 00:30:40,770 you have a model that contains nothing but non bass part children. 405 00:30:40,770 --> 00:30:47,940 So if this model contained a humanoid and a script and some other non bass part stuff like a screen 406 00:30:47,940 --> 00:30:55,980 guy or whatever the case may be, then this model is the exception to this improved model streaming 407 00:30:55,980 --> 00:30:56,730 behavior. 408 00:30:56,730 --> 00:31:03,450 Because this model does not have any bass part children, then the game doesn't need to have to worry 409 00:31:03,450 --> 00:31:08,070 about whether or not the player is within range of any bass part children, because it doesn't have 410 00:31:08,070 --> 00:31:08,520 any. 411 00:31:08,520 --> 00:31:13,980 So that means once our player joins the game, it will replicate this entire model to our player, and 412 00:31:13,980 --> 00:31:16,380 it will also never stream it out. 413 00:31:17,040 --> 00:31:23,040 So if we go and play test the game and we look in the workspace, as you can see, our model that doesn't 414 00:31:23,040 --> 00:31:30,300 have any bass part children has replicated to us even while we are on the improved model streaming behavior. 415 00:31:30,300 --> 00:31:34,020 So the improved model streaming behavior acts a little bit differently. 416 00:31:34,020 --> 00:31:37,560 If a model has bass part children or if it doesn't. 417 00:31:38,540 --> 00:31:44,240 Now, the very last thing we're going to take a look at, for instance, streaming is another property 418 00:31:44,240 --> 00:31:47,150 in our model called Level of Detail. 419 00:31:48,260 --> 00:31:51,020 An automatic is set to disabled. 420 00:31:51,020 --> 00:31:52,160 So that's the default. 421 00:31:52,160 --> 00:31:56,150 But we have another option here called streaming Mesh. 422 00:31:56,150 --> 00:32:02,900 And what this streaming mesh property does is that any models in your game that have this streaming 423 00:32:02,900 --> 00:32:09,200 mesh property enabled, what it's what's going to happen is when you publish your game, Roblox is going 424 00:32:09,200 --> 00:32:16,160 to create a mesh that's basically going to wrap over all of the instances or base parts within your 425 00:32:16,160 --> 00:32:16,880 model. 426 00:32:16,880 --> 00:32:23,000 And then when your player gets far enough away from your model where the model streams out in its place, 427 00:32:23,000 --> 00:32:30,380 it's going to set this what they call an impostor mesh, so it doesn't look like the part has unloaded, 428 00:32:30,380 --> 00:32:31,970 even though it has. 429 00:32:31,970 --> 00:32:38,900 And the streaming mesh level of detail property is very useful for big maps. 430 00:32:39,170 --> 00:32:45,200 Let's say you had a city and a very big map, and when the player got far enough away from the city, 431 00:32:45,200 --> 00:32:47,660 you didn't want to unload that entire city. 432 00:32:47,660 --> 00:32:48,080 But you would. 433 00:32:48,320 --> 00:32:53,600 You would rather keep that city far away, but still visible but not loaded to the player. 434 00:32:53,600 --> 00:32:58,460 Well, that's where you would use a streaming mesh, because once the player gets far enough away from 435 00:32:58,460 --> 00:33:05,090 the city and the server, uh, streams out the city from the player, it's going to put an impostor 436 00:33:05,090 --> 00:33:08,240 mesh in place of those city buildings. 437 00:33:08,990 --> 00:33:13,310 So because I have it set to streaming mesh here, you're going to see what I mean when I play test my 438 00:33:13,310 --> 00:33:13,940 game. 439 00:33:15,200 --> 00:33:21,020 If I go ahead and look behind me, as you can see, that's not actually my model over there. 440 00:33:21,020 --> 00:33:24,170 That is actually an impostor mesh. 441 00:33:24,260 --> 00:33:27,710 So even though we can see our model right here, there is no base part children. 442 00:33:27,710 --> 00:33:34,820 There is an imposter that has basically wrapped over where our parts would actually be. 443 00:33:35,060 --> 00:33:40,820 But then once I actually go and walk over to my model, it's going to get rid of that impostor mesh. 444 00:33:40,820 --> 00:33:41,780 And there we go. 445 00:33:41,780 --> 00:33:46,370 Now the real base parts have loaded in, but then when I walk away from it. 446 00:33:48,000 --> 00:33:50,490 You're going to see the bass parts disappear. 447 00:33:51,270 --> 00:33:55,380 And then in its place is an imposter mesh. 448 00:33:56,620 --> 00:34:02,140 Now, something important to note is that impostor meshes will still take up network data. 449 00:34:02,140 --> 00:34:09,040 So if I go and view on the client here and I open up my network information and we take a look at the 450 00:34:09,040 --> 00:34:15,670 overall incoming data, and even though this client doesn't have that model loaded in, it's just the 451 00:34:15,670 --> 00:34:16,810 impostor mesh. 452 00:34:16,810 --> 00:34:22,150 If I were to start moving around this model on the server, it's also going to start moving that impostor 453 00:34:22,150 --> 00:34:22,690 mesh around. 454 00:34:22,690 --> 00:34:30,760 So if I move it over here, as you can see, the client can also see the model moving, even though 455 00:34:30,760 --> 00:34:37,870 our player doesn't actually have those bass parts loaded in, and instead it is moving the impostor 456 00:34:37,870 --> 00:34:42,280 mesh along with, uh, the model that is being moved on the server. 457 00:34:42,280 --> 00:34:49,420 So as you can see, our overall incoming data is still increasing even though none of the bass parts 458 00:34:49,420 --> 00:34:50,050 are loaded in. 459 00:34:50,050 --> 00:34:56,710 And that's because we have set an imposter mesh in the place of the actual parts in the model. 460 00:34:56,710 --> 00:35:00,670 However, this imposter mesh does not dynamically update. 461 00:35:00,670 --> 00:35:08,050 So if I were to start changing the size and shape and position of these parts inside of the model, 462 00:35:08,140 --> 00:35:11,560 you can see that my impostor mesh is not changing. 463 00:35:11,560 --> 00:35:17,380 If I go and walk over to where my model is at, you're going to see the imposter mesh disappear. 464 00:35:17,380 --> 00:35:20,530 And then there's my actual real bass parts. 465 00:35:20,530 --> 00:35:25,510 And then when I go and walk away and unload those bass parts again. 466 00:35:26,820 --> 00:35:32,910 As you can see, the imposter mesh has now taken place over the parts in my model. 467 00:35:33,970 --> 00:35:40,000 So that's just something important to note, is that streaming messages do not dynamically update during 468 00:35:40,000 --> 00:35:45,850 runtime, and you also cannot create streaming messages during the runtime of your game. 469 00:35:45,850 --> 00:35:49,870 Streaming meshes are only created when you publish the game. 470 00:35:50,660 --> 00:35:59,510 So even if I were to like, for example, create a new part on the server, actually let me anchor this 471 00:35:59,510 --> 00:35:59,810 part. 472 00:35:59,810 --> 00:36:02,450 Let me open up my properties panel, anchor that. 473 00:36:02,990 --> 00:36:06,800 So even if I were to create this new part, put it inside of a model. 474 00:36:06,800 --> 00:36:08,720 Let me change the size real quick. 475 00:36:08,750 --> 00:36:09,920 Do something like that. 476 00:36:10,460 --> 00:36:16,130 Even if I were to set this to streaming mesh, as you can see, the player doesn't see any mesh. 477 00:36:16,130 --> 00:36:21,320 And that's because these impostor meshes are only created when your game is published. 478 00:36:21,880 --> 00:36:28,210 However, if we were to duplicate this model, since this model already has a streaming mesh attached 479 00:36:28,210 --> 00:36:30,670 to it, if I duplicate it and then move it. 480 00:36:30,670 --> 00:36:37,540 As you can see, my player gets to see that other impostor mesh and I can duplicate this multiple times. 481 00:36:38,050 --> 00:36:41,230 So I have three separate different impostor meshes. 482 00:36:41,970 --> 00:36:45,240 And if I go and walk over the real models. 483 00:36:45,240 --> 00:36:45,750 There you go. 484 00:36:45,780 --> 00:36:49,020 We'll load in and then that other model loaded in as well. 485 00:36:49,470 --> 00:36:54,900 But this other model that was created during the runtime of my game, even though we set it to have 486 00:36:54,900 --> 00:37:01,440 a streaming mesh, streaming meshes are not created at runtime, so there's no point in doing that. 487 00:37:02,540 --> 00:37:09,110 Hopefully you now have a better understanding of instant streaming and how you can utilize this awesome 488 00:37:09,110 --> 00:37:11,090 feature in your games. 489 00:37:11,120 --> 00:37:15,470 That is the entirety of instant streaming for now. 490 00:37:15,470 --> 00:37:21,500 They might update it and add more features in the future, but that is the complete extent of instant 491 00:37:21,500 --> 00:37:21,980 streaming. 492 00:37:21,980 --> 00:37:28,040 You have these properties here, and you have two properties in parts where you're able to control and 493 00:37:28,040 --> 00:37:33,110 manipulate how models and bass parts stream in and out of your game. 494 00:37:33,290 --> 00:37:37,580 That's all I have for you in this lecture, and I will see you in the next one.